package com.heima.search.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.service.ApUserSearchService;
import com.heima.search.service.ArticleSearchService;
import com.heima.utils.common.ApUserThreadLocalUtil;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 陈辉
 * @data 2023 9:21
 */
@Service
public class ArticleSearchServiceImpl implements ArticleSearchService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private ApUserSearchService apUserSearchService;

    /**
     * ES文章分页搜索
     * @param userSearchDto
     * @return
     */
    @Override
    public ResponseResult search(UserSearchDto userSearchDto) throws IOException {
        //1.检查参数
        if(userSearchDto == null || StringUtils.isBlank(userSearchDto.getSearchWords())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //异步调用保存搜索记录功能
        ApUser user = ApUserThreadLocalUtil.getUser();
        if (user != null && user.getId() != null) {
            apUserSearchService.insert(userSearchDto.getSearchWords(), user.getId());
        }

        SearchRequest searchRequest = new SearchRequest("app_info_article");
        //1. 封装查询条件  ctrl + P
        searchRequest.source().query(QueryBuilders.boolQuery()
                .must(QueryBuilders.multiMatchQuery(userSearchDto.getSearchWords(), "title", "content"))
                .filter(QueryBuilders.rangeQuery("publishTime").lt(userSearchDto.getMinBehotTime()))
        );

        //2. 封装分页参数
        searchRequest.source().from(userSearchDto.getFromIndex());
        searchRequest.source().size(userSearchDto.getPageSize());
        //3. 封装排序条件
        searchRequest.source().sort("publishTime", SortOrder.DESC);
        //4. 封装高亮字段
        searchRequest.source().highlighter(new HighlightBuilder()
                .field("title")
                .preTags("<font style='color: red; font-size: inherit;'>")
                .postTags("</font>"));

        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //解析response，将结果处理好返回给前端展示
        List<Map> list = new ArrayList<>();
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            Map map = JSONObject.parseObject(sourceAsString,Map.class);

            if (hit.getHighlightFields()!= null && hit.getHighlightFields().size() > 0){
                String highlightTitle = hit.getHighlightFields().get("title").getFragments()[0].toString();
                map.put("h_title",highlightTitle);
            }else {
                map.put("h_title",map.get("title"));
            }

            list.add(map);
        }

        return ResponseResult.okResult(list);
    }
}
